home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
demos
/
GL
/
buttonfly
/
textmap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
7KB
|
323 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* textmap -
* Use texture mapping to draw text.
*
* Paul Haeberli - 1991
*
*/
#include "gl/gl.h"
#include "gl/image.h"
#include "textmap.h"
static texfnt *curtfnt;
static unsigned char *fb;
static unsigned char *gptr;
/*
* get metric data into image
*
*/
static initget()
{
gptr = fb;
}
static getbytes(buf,n)
unsigned char *buf;
int n;
{
while(n--)
*buf++ = *gptr++;
}
static fixrow(sptr,n)
unsigned short *sptr;
int n;
{
while(n--) {
*sptr = *sptr + (0xff<<8);
*sptr = (*sptr<<8) + 0xff;
sptr++;
}
}
texfnt *readtexfont(name)
char *name;
{
texfnt *tfnt;
IMAGE *image;
unsigned char *cptr;
unsigned short *sbuf, *sptr;
short advancecell, xadvance;
short llx, lly, urx, ury, ox, oy;
int i, y, c, extralines;
texchardesc *cd;
tfnt = (texfnt *)malloc(sizeof(texfnt));
image = iopen(name,"r");
if(!image) {
fprintf(stderr,"textmap: can't open font image %s\n",name);
return 0;
}
extralines = image->ysize-image->xsize;
if(extralines<1) {
fprintf(stderr,"textmap: bad input font!!\n");
return 0;
}
fb = (unsigned char *)malloc(image->xsize*extralines);
sbuf = (unsigned short *)malloc(image->xsize*sizeof(short));
cptr = fb;
for(y=image->xsize; y<image->ysize; y++) {
getrow(image,sbuf,y,0);
stoc(sbuf,cptr,image->xsize);
cptr += image->xsize;
}
initget();
tfnt->rasxsize = image->xsize;
tfnt->rasysize = image->xsize;
getbytes(&tfnt->charmin,sizeof(short));
getbytes(&tfnt->charmax,sizeof(short));
getbytes(&tfnt->pixhigh,sizeof(float));
getbytes(&advancecell,sizeof(short));
tfnt->nchars = tfnt->charmax-tfnt->charmin+1;
tfnt->chars = (texchardesc *)malloc(tfnt->nchars*sizeof(texchardesc));
tfnt->rasdata = (unsigned short *)malloc(tfnt->rasxsize*tfnt->rasysize*sizeof(long));
sptr = tfnt->rasdata;
for(y=0; y<tfnt->rasysize; y++) {
getrow(image,sptr,y,0);
fixrow(sptr,tfnt->rasxsize);
sptr += tfnt->rasxsize;
}
iclose(image);
cd = tfnt->chars;
for(i=0; i<tfnt->nchars; i++) {
c = tfnt->charmin+i;
getbytes(&xadvance,sizeof(short));
getbytes(&llx,sizeof(short));
getbytes(&lly,sizeof(short));
getbytes(&urx,sizeof(short));
getbytes(&ury,sizeof(short));
getbytes(&ox,sizeof(short));
getbytes(&oy,sizeof(short));
cd->movex = xadvance/(float)advancecell;
if(llx>=0) {
cd->haveimage = 1;
cd->llx = (llx-ox)/tfnt->pixhigh;
cd->lly = (lly-oy)/tfnt->pixhigh;
cd->urx = (urx-ox+1)/tfnt->pixhigh;
cd->ury = (ury-oy+1)/tfnt->pixhigh;
cd->tllx = llx/(float)tfnt->rasxsize;
cd->tlly = lly/(float)tfnt->rasysize;
cd->turx = (urx+1)/(float)tfnt->rasxsize;
cd->tury = (ury+1)/(float)tfnt->rasysize;
cd->data[0] = cd->tllx;
cd->data[1] = cd->tlly;
cd->data[2] = cd->llx;
cd->data[3] = cd->lly;
cd->data[4] = cd->turx;
cd->data[5] = cd->tlly;
cd->data[6] = cd->urx;
cd->data[7] = cd->lly;
cd->data[8] = cd->turx;
cd->data[9] = cd->tury;
cd->data[10] = cd->urx;
cd->data[11] = cd->ury;
cd->data[12] = cd->tllx;
cd->data[13] = cd->tury;
cd->data[14] = cd->llx;
cd->data[15] = cd->ury;
cd->data[16] = cd->llx;
cd->data[17] = cd->lly;
cd->data[18] = cd->urx;
cd->data[19] = cd->lly;
cd->data[20] = cd->urx;
cd->data[21] = cd->ury;
cd->data[22] = cd->llx;
cd->data[23] = cd->ury;
} else {
cd->haveimage = 0;
}
cd++;
}
free(fb);
free(sbuf);
return tfnt;
}
static float s_tmprops[] = {
TX_MINFILTER,
TX_BILINEAR,
TX_MAGFILTER,
TX_SHARPEN,
TX_NULL,
};
static float b_tmprops[] = {
TX_MINFILTER,
TX_BILINEAR,
TX_MAGFILTER,
TX_BILINEAR,
TX_NULL,
};
static float *tmprops = b_tmprops;
static float tvprops[] = {
TV_MODULATE,
TV_NULL,
};
texfont(tfnt)
texfnt *tfnt;
{
texdef2d(1,2,tfnt->rasxsize,tfnt->rasysize,
(unsigned long *)tfnt->rasdata,5,tmprops);
tevdef(1,2,tvprops);
texbind(0,1);
tevbind(0,1);
curtfnt = tfnt;
}
float texstrwidth(str)
char *str;
{
unsigned int c;
int charmin, tnchars;
texfnt *tfnt;
texchardesc *cdbase, *cd;
float xpos;
tfnt = curtfnt;
if(!tfnt) {
fprintf(stderr,"texstrwidth: no texfont set!!\n");
return;
}
charmin = tfnt->charmin;
tnchars = tfnt->nchars;
cdbase = tfnt->chars;
xpos = 0.0;
while(*str) {
c = *str-charmin;
if(c<tnchars) {
cd = cdbase+c;
xpos += cd->movex;
}
str++;
}
return xpos;
}
texcharstr(str)
unsigned char *str;
{
unsigned int c;
int charmin, tnchars;
texfnt *tfnt;
texchardesc *cdbase, *cd;
float *fdata, xpos;
tfnt = curtfnt;
if(!tfnt) {
fprintf(stderr,"texcharstr: no texfont set!!\n");
return;
}
charmin = tfnt->charmin;
tnchars = tfnt->nchars;
cdbase = tfnt->chars;
xpos = 0.0;
while(*str) {
c = *str-charmin;
if(c<tnchars) {
cd = cdbase+c;
if(cd->haveimage) {
fdata = cd->data;
fdata[16] = fdata[2]+xpos;
fdata[18] = fdata[6]+xpos;
fdata[20] = fdata[10]+xpos;
fdata[22] = fdata[14]+xpos;
bgnpolygon();
t2f(&fdata[0]);
v2f(&fdata[16]);
t2f(&fdata[4]);
v2f(&fdata[18]);
t2f(&fdata[8]);
v2f(&fdata[20]);
t2f(&fdata[12]);
v2f(&fdata[22]);
endpolygon();
}
xpos += cd->movex;
}
str++;
}
}
texfntinit(file)
char *file;
{
static int once = 0;
static texfnt *tfnt;
if (!once) {
char buf[16];
gversion(buf);
if (strncmp(buf, "GL4DRE",6) == 0)
tmprops = s_tmprops;
tfnt = readtexfont(file);
if(!tfnt ) {
fprintf(stderr,"texfntinit: can't open input font %s\n", file);
return(-1);
}
texfont(tfnt);
}
return 0;
}
float texfntwidth(str)
char *str;
{
return texstrwidth(str)*12.5/6.;
}
texfntstroke(s, xoffset, yoffset)
char *s;
float xoffset, yoffset;
{
blendfunction(BF_SA,BF_MSA);
pushmatrix();
translate(xoffset,yoffset,0.0);
scale(12.5, 12.5, 12.5);
texcharstr(s);
popmatrix();
blendfunction(BF_ONE,BF_ZERO);
}